﻿using System;

namespace Patterns.Command {

    public class AbstractExample {
        public static void Run() {
            // Create receiver, command, and invoker
            Receiver receiver = new Receiver();
            AbstractCommand command = new ConcreteCommand(receiver);
            Invoker invoker = new Invoker();

            // Set and execute command
            invoker.SetCommand(command);
            invoker.ExecuteCommand();
        }
    }

    // "Command"
    abstract class AbstractCommand {
        protected Receiver receiver;

        // Constructor
        public AbstractCommand(Receiver receiver) {
            this.receiver = receiver;
        }

        public abstract void Execute();
    }

    // "ConcreteCommand"
    class ConcreteCommand : AbstractCommand {
        // Constructor
        public ConcreteCommand(Receiver receiver)
            : base(receiver) { }

        public override void Execute() {
            receiver.Action();
        }
    }

    // "Receiver"
    class Receiver {
        public void Action() {
            Console.WriteLine("Called Receiver.Action()");
        }
    }

    // "Invoker"
    class Invoker {
        private AbstractCommand command;

        public void SetCommand(AbstractCommand command) {
            this.command = command;
        }

        public void ExecuteCommand() {
            command.Execute();
        }
    }
}
